﻿using Goooodbye.Core.Models;
using Goooodbye.Core.Repositories;
using Goooodbye.Core.Services;
using Goooodbye.Core.Services.Impl;
using Goooodbye.Infrastructure.Repositories;
using Goooodbye.Infrastructure.Services;
using NLog;
using SimpleInjector;
using SimpleInjector.Diagnostics;
using System;
using System.Data;
using System.Data.SQLite;
using System.Reflection;
using System.Windows.Forms;

namespace Goooodbye.Presentation.WinFormsApp
{
    internal static class Program
    {
        private static readonly Logger logger = LogManager.GetLogger(Assembly.GetExecutingAssembly().GetName().Name);
        private static readonly string connectionString = $"Data Source={Application.StartupPath}\\app_data.db;Version=3;";

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            logger.Info("Launch");
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(Bootstrap().GetInstance<FormMain>());
            logger.Info("Exit");
        }

        private static Container Bootstrap()
        {
            // 1. Create a new Simple Injector container
            var container = new Container();

            // 2. Configure the container (register)
            container.Register<IDbConnection>(() => new SQLiteConnection(connectionString), Lifestyle.Singleton);
            container.Register<IDictRepository, DictRepository>();
            container.Register<IDictService, DictService>();
            /*
             * 对于(可能)存在多个实现类的接口，需要使用条件注入。
             * 通过依赖方构造函数的形参名，匹配对应的实现类
             */
            container.RegisterConditional<IImportService, DictImportService>(c => c.Consumer.Target.Name.StartsWith("dict"));
            container.RegisterConditional<IExportService<DictModel>, DictExportService>(c => c.Consumer.Target.Name.StartsWith("dict"));

            AutoRegisterWindowsForms(container);

            // 3. Verify your configuration
            container.Verify();

            return container;
        }

        private static void AutoRegisterWindowsForms(Container container)
        {
            var types = container.GetTypesToRegister<Form>(typeof(Program).Assembly);

            foreach (var type in types)
            {
                var registration = Lifestyle.Transient.CreateRegistration(type, container);
                registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent, "Forms should be disposed by app code; not by the container.");
                container.AddRegistration(type, registration);
            }
        }
    }
}
